/* TITLE BikiROM MegaBoard Bootloader Encryptor v0.2 */
/* Author: Chris Collins */
/* Last Modified: 04/01/2006 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <io.h>

#define Page 0x1EF
#define PageBlock 128
#define ByteBlock 256


int main(void)
{
	unsigned char CypherBlock[37];
	unsigned char CertBlock[22];
	int Vector;
	char InputFirmware[40];	// For user to enter File name
	FILE  *infilep;	// Pointer to file
	FILE  *outfilep;

	int i;
	char Pause;
	unsigned char Initial_Vector;
	unsigned char Incoming_Byte;
	unsigned char Encrypted_Byte;
	unsigned char Certification_Byte;
	unsigned char Page_Size;
	int Exit;


	/* Welcome Screen */
	printf("\n == BikiROM MegaBoard Operating System Encryptor v0.2 - Extended Cypherblock == \n");

            CypherBlock[0] = (unsigned char)228;
            CypherBlock[1] = (unsigned char)173;
            CypherBlock[2] = (unsigned char)143;
            CypherBlock[3] = (unsigned char)120;
            CypherBlock[4] = (unsigned char)97;
            CypherBlock[5] = (unsigned char)44;
            CypherBlock[6] = (unsigned char)13;
            CypherBlock[7] = (unsigned char)5;
            CypherBlock[8] = (unsigned char)176;
            CypherBlock[9] = (unsigned char)169;
            CypherBlock[10] = (unsigned char)66;
            CypherBlock[11] = (unsigned char)180;
            CypherBlock[12] = (unsigned char)88;
            CypherBlock[13] = (unsigned char)125;
            CypherBlock[14] = (unsigned char)225;
            CypherBlock[15] = (unsigned char)207;
            CypherBlock[16] = (unsigned char)117;
            CypherBlock[17] = (unsigned char)157;
            CypherBlock[18] = (unsigned char)220;
            CypherBlock[19] = (unsigned char)63;
            CypherBlock[20] = (unsigned char)193;
            CypherBlock[21] = (unsigned char)5;
            CypherBlock[22] = (unsigned char)104;
            CypherBlock[23] = (unsigned char)133;
            CypherBlock[24] = (unsigned char)92;
            CypherBlock[25] = (unsigned char)148;
            CypherBlock[26] = (unsigned char)86;
            CypherBlock[27] = (unsigned char)31;
            CypherBlock[28] = (unsigned char)10;
            CypherBlock[29] = (unsigned char)109;
            CypherBlock[30] = (unsigned char)164;
            CypherBlock[31] = (unsigned char)178;
            CypherBlock[32] = (unsigned char)29;
            CypherBlock[33] = (unsigned char)131;
            CypherBlock[34] = (unsigned char)211;
            CypherBlock[35] = (unsigned char)208;
            CypherBlock[36] = (unsigned char)206;

	CertBlock[1] = 0x94;
	CertBlock[0] = 0x0C;
	CertBlock[3] = 0x00;
	CertBlock[2] = 0x00;
	CertBlock[5] = 0x00;
	CertBlock[4] = 0x00;
	CertBlock[7] = 0x90;
	CertBlock[6] = 0x54;
	CertBlock[9] = 0x94;
	CertBlock[8] = 0x65;
	CertBlock[11] = 0x94;
	CertBlock[10] = 0x73;
	CertBlock[13] = 0x90;
	CertBlock[12] = 0x74;
	CertBlock[15] = 0x92;
	CertBlock[14] = 0x20;
	CertBlock[17] = 0x21;
	CertBlock[16] = 0x4F;
	CertBlock[19] = 0x0D;
	CertBlock[18] = 0x4B;
	CertBlock[21] = 0x95;
	CertBlock[20] = 0x21;

	randomize();

	Initial_Vector = (unsigned char)random(70) / 2;

	printf("\n Initial Vector: %d\n", Initial_Vector);

/*	for(i=0;i<13;i++)
	{
	CypherBlock[i] = (unsigned char)(rand() % 256);
     //	printf("%d , ", CypherBlock[i]);
	}*/


	//do {
		//printf("\n Enter source firmware filename (must be in BINARY form): ");
		//fgets(InputFirmware, sizeof InputFirmware, stdin);  // Reads filename from keyboard

		//InputFirmware[strlen(InputFirmware) - 1] = '\0';  // Repairs carriage return problem

		//infilep = fopen(InputFirmware, "rb");  // open file as read for input
		infilep = fopen("biki_os.bin", "rb");  // open file as read for input

		if (infilep == NULL)  // if NULL, file has not been opened
		{	
			printf("\n ** ERROR: Cannot open BIKI_OS.BIN for input\n");
		}

	//} while (infilep == NULL);	// repeat this until user gets file right

	else
	{

	printf("\n Successfully opened BIKI_OS.BIN ... processing... \n");


	outfilep = fopen("BIKI_OS.ENC", "wb");

	fwrite(&Initial_Vector, sizeof (unsigned char), 1, outfilep);

	Vector = (int)Initial_Vector;

	Page_Size = 0;

	do
	{
		Exit = fread(&Incoming_Byte, sizeof (unsigned char), 1, infilep);

//		printf("%d, %d\n", Exit, (int)Incoming_Byte);


		if (Exit == 1)
		{
		Encrypted_Byte = Incoming_Byte ^ (unsigned char)CypherBlock[Vector];
		fwrite(&Encrypted_Byte, sizeof (unsigned char), 1, outfilep);
		Page_Size++;
		Vector++;
		if (Vector > 36) Vector = 0;

		Encrypted_Byte = (unsigned char)random(256);
		fwrite(&Encrypted_Byte, sizeof (unsigned char), 1, outfilep);
		Encrypted_Byte = (unsigned char)random(256);
		fwrite(&Encrypted_Byte, sizeof (unsigned char), 1, outfilep);
		}


	}
	while (Exit == 1);

	// Firmware Certification Block

	for(i=0;i<=21;i++)
	{
	Certification_Byte = CertBlock[i] ^ (unsigned char)CypherBlock[Vector];
	fwrite(&Certification_Byte, sizeof (unsigned char), 1, outfilep);
	Page_Size++;
	Vector++;
	if (Vector > 36) Vector = 0;

	Encrypted_Byte = (unsigned char)random(256);
	fwrite(&Encrypted_Byte, sizeof (unsigned char), 1, outfilep);
	Encrypted_Byte = (unsigned char)random(256);
	fwrite(&Encrypted_Byte, sizeof (unsigned char), 1, outfilep);
	}

	// FF padding block
	//printf("Page Size: %d", (int)Page_Size);

	if (Page_Size != 0)
	{
		for(i=0;i<=(255-Page_Size);i++)
		{
		Certification_Byte = 0xFF ^ (unsigned char)CypherBlock[Vector];
		fwrite(&Certification_Byte, sizeof (unsigned char), 1, outfilep);
		Vector++;
		if (Vector > 36) Vector = 0;

		Encrypted_Byte = (unsigned char)random(256);
		fwrite(&Encrypted_Byte, sizeof (unsigned char), 1, outfilep);
		Encrypted_Byte = (unsigned char)random(256);
		fwrite(&Encrypted_Byte, sizeof (unsigned char), 1, outfilep);
		}
	}


	fclose(outfilep);
	fclose(infilep);	// close files

	printf("\n Encryption complete. Output in BIKI_OS.ENC\n");
	}

	//printf("\n Press ENTER to Exit... ");
	//scanf("%c", Pause);  // waits for response from keyboard

	return 0;
}
